package com.zengdada.authority.controller;

import com.github.pagehelper.PageInfo;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.zengdada.authority.config.security.intercept.AuthorityUtil;
import com.zengdada.authority.exception.RoutineException;
import com.zengdada.authority.model.AppUser;
import com.zengdada.authority.service.AppUserAuthorityService;
import com.zengdada.authority.utils.HEXUtil;
import com.zengdada.authority.utils.JsonMessage;
import com.zengdada.authority.utils.mapper.Page;
import com.zengdada.authority.utils.mapper.Sort;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;

import static com.zengdada.authority.utils.JsonMessage.fail;
import static com.zengdada.authority.utils.JsonMessage.success;

@Api(tags = "用户控制器")
@Controller
@RequestMapping("/authority/user")
public class AppUserAuthorityController {

    @Value("${web.config.authority.user.login.success.page.url:/authority/back.html}")
    private String loginSuccessPageUrl;

    @Value("${web.config.authority.user.login.page.url:/authority/user/login.html}")
    private String loginPageUrl;

    @Value("${web.config.authority.user.login.url:/authority/user/login.do}")
    private String loginUrl;

    @Value("${web.config.authority.user.logout.url:/authority/user/logout.html}")
    private String logoutUrl;

    @Value("${web.config.authority.user.change.password.url:/authority/user/change_password.do}")
    private String changePasswordUrl;

    @Value("${web.company.info.name:zsa}")
    private String companyName;
    @Value("${web.company.info.english.name:ZSA}")
    private String companyEnglishName;
    @Value("${web.company.info.index.url:http://www.zengdada.cn}")
    private String companyIndexUrl;
    @Autowired
    @Qualifier("appUserAuthorityServiceImpl")
    AppUserAuthorityService appUserService;
    @Autowired
    AuthorityUtil authorityUtil;


    @ApiOperation("用户登录页面")
    @ApiImplicitParam(name = "reference", value = "上一个请求页面的加密值", dataType = "String")
    @GetMapping(value = "/login.html")
    public String page(HttpServletRequest request,
                       @ModelAttribute(value = "reference") String reference) {
        request.setAttribute("title", "用户登录");
        request.setAttribute("reference", reference);
        request.setAttribute("loginUrl", loginUrl);
        request.setAttribute("companyInfo", new HashMap<String, String>() {{
            put("name", companyName);
            put("englishName", companyEnglishName);
            put("indexUrl", companyIndexUrl);
        }});
        return "authority/user/login";
    }

    /**
     * 登录请求
     *
     * @param appUser    应包含account、password
     * @param reference  上一次的请求地址，用作会登录后回调
     * @param request
     * @param attributes
     * @return
     */
    @ApiOperation("用户登录请求")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "reference", value = "上一个请求页面的加密值", dataType = "String"),
            @ApiImplicitParam(name = "appUser", value = "登录的用户信息", dataType = "AppUser", dataTypeClass = AppUser.class)
    })
    @ApiOperationSupport(order = 10,includeParameters = "reference,account,password")
    @PostMapping(value = "/login.do")
    public String login(AppUser appUser,
                        @ModelAttribute(value = "reference") String reference,
                        HttpServletRequest request, HttpSession session, RedirectAttributes attributes) {
        try {
            AppUser user = appUserService.login(appUser);
            authorityUtil.initAuthority(request, user);
            session.setAttribute("user_logout_url", logoutUrl);
            return String.format("redirect:%s", ("".equals(reference) ? loginSuccessPageUrl : HEXUtil.decrypt(reference, "login_before_request", HEXUtil.CipherType.AES128)));
        } catch (Exception e) {
            attributes.addFlashAttribute("account", appUser.getAccount());
            attributes.addFlashAttribute("reference", reference);
            attributes.addFlashAttribute("errorMsg", "登陆失败：" + ("账号不存在".equals(e.getMessage()) || "密码错误".equals(e.getMessage()) ? "账号或密码错误！" : e.getMessage()));
            return String.format("redirect:%s", loginPageUrl);
        }
    }

    @GetMapping(value = "/logout.html")
    public String logout() {
        authorityUtil.clearSecurityContext();
        return String.format("redirect:%s", loginPageUrl);
    }

    /**
     * 用户密码修改
     *
     * @param request
     * @return
     */

    @GetMapping(value = "/change_password.html")
    public String toChangePwd(HttpServletRequest request) {
        AppUser user = authorityUtil.getLoginUser();
        request.setAttribute("userName", user.getName());
        request.setAttribute("changePasswordUrl", changePasswordUrl);
        return "authority/user/change_password";
    }


    @RequestMapping(value = "/change_password.do", method = RequestMethod.POST)
    @ResponseBody
    public JsonMessage changePwd(@RequestParam("oldPassword") String oldPassword,
                                 @RequestParam("password") String password,
                                 @RequestParam("confirmPassword") String confirmPassword,
                                 HttpServletRequest request) {
        try {
            AppUser user = authorityUtil.getLoginUser();
            appUserService.changPassword(user, oldPassword, password, confirmPassword);
            authorityUtil.updateLoginUser(); // 更新缓存中的用户信息
            return success("密码修改成功！", new HashMap<String, String>() {{
                put("action", request.getContextPath() + logoutUrl);
            }});
        } catch (Exception e) {
            return fail("修改密码失败：" + e.getMessage());
        }
    }


    /**
     * 列表页面
     *
     * @return
     */
    @GetMapping(value = "/list.html")
    public String listPage() {
        return "authority/user/list";
    }

    @RequestMapping(value = "/list.do", method = RequestMethod.POST)
    @ResponseBody
    public JsonMessage list(@RequestParam(value = "searchs", required = false) String searchs, Page page, Sort sort) {
        try {
            PageInfo<Map<String, Object>> pageInfo = appUserService.selectDetailedPageInfoByParam(searchs, page, sort);
            return success(pageInfo.getList(), pageInfo.getTotal());
        } catch (Exception e) {
            return fail(e.getMessage());
        }
    }

    /**
     * 编辑页面
     */
    @GetMapping(value = "/edit.html")
    public String edit(@RequestParam(value = "id", defaultValue = "") String id, HttpServletRequest request) {
        if (!"".equals(id))
            request.setAttribute("user", appUserService.selectById(id));
        return "authority/user/add";
    }

    @RequestMapping(value = "/save.do", method = RequestMethod.POST)
    @ResponseBody
    public JsonMessage save(AppUser user) {
        try {
            if (user == null || "".equals(user.getPassword())) throw new RoutineException("参数异常！！");
            if (StringUtils.isBlank(user.getId())) appUserService.add(user);
            else appUserService.updateById(user);
            return success("保存成功", null);
        } catch (Exception e) {
            return fail("保存失败：" + e.getMessage());
        }
    }

    @RequestMapping(value = "/del.do", method = RequestMethod.POST)
    @ResponseBody
    public JsonMessage del(@RequestParam(value = "id", defaultValue = "") String id) {
        try {
            if ("".equals(id)) throw new RoutineException("参数异常！！");
            if (appUserService.deleteById(id) == 0) throw new RoutineException("未找到相关信息！！");
            return success("删除信息成功", null);
        } catch (Exception e) {
            return fail("删除失败：" + e.getMessage());
        }
    }


}
